module nco_modulator (
           input wire clk,
           input wire rst_n,
           input wire din,
           input wire din_valid,
           input wire [1: 0] mode,
           input wire [31: 0] fcw1,
           input wire [31: 0] fcw2,
           input wire [31: 0] phase_offset,
           input wire [3: 0] amplitude_shift,
           input wire load,
           output wire [14: 0] lut_addr,
           input wire signed [11: 0] lut_data,
           output wire [11: 0] out,
           output reg out_valid
       );

reg [11: 0] out_reg;
reg [31: 0] phase_reg;
reg [31: 0] freq_reg_1;
reg [31: 0] freq_reg_2;
reg [31: 0] phase_offset_reg;
reg [3: 0] amplitude_shift_reg;

/* 缓冲2拍寄存 */
reg [1: 0] din_buf;
reg [1: 0] din_valid_buf;
wire din_bfd = din_buf[1];
wire din_valid_bfd = din_valid_buf[1];
// 缓冲执行块
always @(posedge clk) begin
    if (!rst_n) begin
        din_buf <= 0;
        din_valid_buf <= 0;
    end else begin
        din_buf <= {din_buf[0], din};
        din_valid_buf <= {din_valid_buf[0], din_valid};
    end
end

/* 输出地址 */
wire [31: 0] addr =
     (mode == 2'b10 && din_bfd) ? phase_reg + phase_offset_reg : phase_reg;
assign lut_addr = addr[31: 17];

/* 输出状态判定 */
assign out = (out_valid) ? out_reg : 0;

/* 程序执行块，用于执行主要的调制程序 */
always @(posedge clk) begin
    if (!rst_n) begin
        phase_reg <= 0;
        freq_reg_1 <= 0;
        freq_reg_2 <= 0;
        phase_offset_reg <= 0;
        amplitude_shift_reg <= 0;
        out_reg <= 0;
        out_valid <= 0;
    end else begin
        // 单开线程判断加载状态，并且加载数据进入系统
        if (load) begin
            freq_reg_1 <= fcw1;
            freq_reg_2 <= fcw2;
            phase_offset_reg <= phase_offset;
            amplitude_shift_reg <= amplitude_shift;
        end else ;

        /* 开始主要调制器的执行工作 */
        case (mode)
            // 没有调制
            2'b00: begin
                if (!din_valid_bfd) begin
                    out_valid <= 0;
                end else begin
                    out_valid <= 1;
                    out_reg <= lut_data;
                    phase_reg <= phase_reg + freq_reg_1;
                end
            end

            // ASK调制
            2'b01: begin
                if (!din_valid_bfd) begin
                    out_valid <= 0; 
                end else begin
                    out_valid <= 1;
                    out_reg <= (din_bfd) ? lut_data : (lut_data >>> amplitude_shift_reg);
                    phase_reg <= phase_reg + freq_reg_1;
                end
            end

            // PSK调制
            2'b10: begin
                if (!din_valid_bfd) begin
                    out_valid <= 0;
                end else begin
                    out_valid <= 1;
                    out_reg <= lut_data;
                    phase_reg <= phase_reg + freq_reg_1;
                end
            end

            // FSK调制
            2'b11: begin
                if (!din_valid_bfd) begin
                    out_valid <= 0; 
                end else begin
                    out_valid <= 1;
                    out_reg <= lut_data;
                    phase_reg <= phase_reg + ((din_bfd) ? freq_reg_1 : freq_reg_2);
                end
            end

        endcase

    end
end


endmodule

